package com.wentao.thisService.service.impl;

import com.wentao.thisCommon.model.RequestBase;
import com.wentao.thisCommon.model.ResultBase;
import com.wentao.thisFacade.common.enums.ConstString;
import com.wentao.thisFacade.common.enums.ExceptionCode;
import com.wentao.thisFacade.common.enums.SuccessCode;
import com.wentao.thisFacade.domain.reqeust.HotelDetailsRequest;
import com.wentao.thisFacade.domain.reqeust.UserNameUserIdRequest;
import com.wentao.thisFacade.domain.result.FileResult;
import com.wentao.thisFacade.domain.result.UploadResult;
import com.wentao.thisFacade.domain.result.VersionResult;
import com.wentao.thisService.common.CommonFunction;
import com.wentao.thisService.common.TokenVerify;
import com.wentao.thisService.common.upload.FileExecutor;
import com.wentao.thisService.common.upload.UploadFileInfo;
import com.wentao.thisService.mapper.FileDao;
import com.wentao.thisService.mapper.VersionDao;
import com.wentao.thisService.model.FileEntity;
import com.wentao.thisService.model.VersionEntity;
import com.wentao.thisService.service.FileService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: ZhaiYanTao
 * @Date: 2020/3/27 10:20
 * @Description: 文件（图片，APK）service实现
 */
@Service
public class FileServiceImpl implements FileService {

    @Value("${readFile.host.ip}")
    private String readFileHostIp;

    @Value("${apkUpload.host.ip}")
    private String apkUploadIP;

    @Value("${apkUpload.dir.rootPath}")
    private String apkRootPath;

    @Value("${apkUpload.dir.subPath}")
    private String apkSubPath;

    @Autowired
    private FileExecutor fileExecutor;

    @Autowired
    private FileDao fileDao;

    @Autowired
    private VersionDao versionDao;

    /**
     * @see FileService#upload(MultipartFile, String, String)
     */
    @Transactional
    @Override
    public UploadResult upload(@RequestParam("file") MultipartFile file, @RequestParam("uploadType") String uploadType, @RequestParam("uploadCode") String uploadCode) throws Exception {
        UploadFileInfo upload_path = fileExecutor.upladFile(file, ConstString.UPLOAD_File);
        upload_path.setOriginalFileName(file.getOriginalFilename());
//        UploadResult result = saveFile(uploadCode, uploadType, file.getOriginalFilename(), upload_path.getRelativePath());
        FileEntity en = new FileEntity();
        en.setCode(uploadCode);// 此值用来存companyCode，关联图片到酒店
        en.setUploadType("D");
        en.setFileName(file.getOriginalFilename());
        en.setFileCodeType(uploadType);// 此值用来存PhotoCode(枚举)，区分照片类型
        en.setPath(upload_path.getRelativePath());
        en.setOwnId(0L);
        en.setCreateTime(CommonFunction.GetNowDateString());
        en.setCreateBy("upload");
        fileDao.Insert(en);
        UploadResult result = new UploadResult();
        result.setServerUrl(upload_path.getRelativePath());

        // 修改返回结果，让结果能直接在网页打开
        String matchChar = "\\";
        String replaceChar = "/";
        String serverUrl = result.getServerUrl();
        if (serverUrl.indexOf(matchChar) > 0) {
            String replace = serverUrl.replace(matchChar, replaceChar);
            result.setServerUrl(String.format("%s%s", readFileHostIp, replace));
        }

        return result;
    }

    /**
     * @see FileService#upload(MultipartFile, String, String)
     */
    @Transactional
    @Override
    public UploadResult uploadOSS(@RequestParam("file") MultipartFile file, @RequestParam("uploadType") String uploadType, @RequestParam("uploadCode") String uploadCode) throws Exception {
        UploadFileInfo upload_path = fileExecutor.uploadOSS(file);
        upload_path.setOriginalFileName(file.getOriginalFilename());
        UploadResult result = saveFile(uploadCode, uploadType, file.getOriginalFilename(), upload_path.getRelativePath());
        return result;
    }


    /**
     * @see FileService#hotelFiles(HotelDetailsRequest)
     */
    @Override
    @TokenVerify
    public List<FileResult> hotelFiles(HotelDetailsRequest hotelDetailsRequest) throws Exception {
        List<FileResult> fileResultList = new ArrayList<>();

        FileEntity searchFile = new FileEntity();
        searchFile.setCode(hotelDetailsRequest.getCompanyCode());
        searchFile.setStatus("Y");
        List<FileEntity> fileEntityList = fileDao.Search(searchFile);

        if (StringUtils.isNotBlank(hotelDetailsRequest.getCompanyCode()) && null != fileEntityList && fileEntityList.size() > 0) {
            for (FileEntity fileEntity : fileEntityList) {
                if ("Y".equals(fileEntity.getStatus())) {
                    FileResult fileResult = transform(fileEntity);
                    // 修改path，让path结果能直接在网页打开
                    String matchChar = "\\";
                    String replaceChar = "/";
                    String path = fileResult.getPath();
                    if (path.indexOf(matchChar) > 0) {
                        String replace = path.replace(matchChar, replaceChar);
                        fileResult.setPath(String.format("%s%s", readFileHostIp, replace));
                    }
                    fileResultList.add(fileResult);
                }
            }
        }

        return fileResultList;
    }

    /**
     * @see FileService#saveAPK(MultipartFile, Integer, String, String, Integer, Integer, String)
     */
    @Override
    public VersionResult saveAPK(MultipartFile file, Integer versionCode, String versionName, String updateContent, Integer compatibleMinCode, Integer compatibleMaxCode, String createBy) throws Exception {

        // 保存apk到本地
        String suffixName = fileExecutor.getFileSuffixName(file);
        String fileName = versionName + suffixName;
        java.nio.file.Path filePath = Paths.get(apkRootPath, apkSubPath, fileName);
        FileUtils.copyInputStreamToFile(file.getInputStream(), new File(String.valueOf(filePath)));

        // 保存t_version
        VersionEntity saveVersion = new VersionEntity();
        saveVersion.setVersionCode(versionCode);
        saveVersion.setVersionName(versionName);
        saveVersion.setUpdateContent(updateContent);
        saveVersion.setUrl(Paths.get(apkSubPath, fileName).toString());
        saveVersion.setCompatibleMinCode(compatibleMinCode);
        saveVersion.setCompatibleMaxCode(compatibleMaxCode);
        saveVersion.setValidMark("1");
        saveVersion.setDeleteMark("0");
        saveVersion.setCreateTime(CommonFunction.GetNowDateString());
        saveVersion.setCreateBy(createBy);
        versionDao.Insert(saveVersion);

        // 版本保存结果
        VersionResult versionResult = transform(saveVersion);

        // 修改url，让结果能直接在网页打开
        String matchChar = "\\";
        String replaceChar = "/";
        if (versionResult.getUrl().contains(matchChar)) {
            versionResult.setUrl(String.format("%s%s", apkUploadIP, versionResult.getUrl().replace(matchChar, replaceChar)));
        }

        return versionResult;
    }

    // TODO: 2020/3/27 保存数据库，是否需要
    private UploadResult saveFile(String uploadCode, String uploadType, String fileName, String path) {
        FileEntity en = new FileEntity();
        en.setCode(uploadCode);// 此值用来存companyCode，关联图片到酒店
        en.setUploadType("D");
        en.setFileName(fileName);
        en.setFileCodeType(uploadType);// 此值用来存PhotoCode(枚举)，区分照片类型
        en.setPath(path);
        en.setOwnId(0L);
        en.setCreateTime(CommonFunction.GetNowDateString());
        en.setCreateBy("upload");
        fileDao.Insert(en);
        UploadResult result = new UploadResult();
        result.setServerUrl(path);
        return result;
    }

    /**
     * 转换方法，版本PO转VO
     *
     * @param source 版本PO
     * @return 版本VO
     */
    private VersionResult transform(VersionEntity source) {
        if (null != source) {
            VersionResult target = new VersionResult();

            target.setId(source.getId());
            target.setVersionCode(source.getVersionCode());
            target.setVersionName(source.getVersionName());
            target.setUpdateContent(source.getUpdateContent());
            target.setUrl(source.getUrl());
            target.setCompatibleMinCode(source.getCompatibleMinCode());
            target.setCompatibleMaxCode(source.getCompatibleMaxCode());
            target.setValidMark(source.getValidMark());
            target.setDeleteMark(source.getDeleteMark());
            target.setCreateTime(source.getCreateTime());
            target.setCreateBy(source.getCreateBy());

            return target;
        }
        return null;
    }

    /**
     * 转换方法
     *
     * @param source PO
     * @return BO
     */
    private FileResult transform(FileEntity source) {
        if (null != source) {
            FileResult target = new FileResult();
            target.setId(source.getId());
            target.setCode(source.getCode());
            target.setFileCodeType(source.getFileCodeType());
            target.setFileName(source.getFileName());
            target.setPath(source.getPath());
            target.setUploadType(source.getUploadType());
            target.setStatus(source.getStatus());
            target.setOwnId(source.getOwnId());
            target.setCreateTime(source.getCreateTime());
            target.setCreateBy(source.getCreateBy());
            target.setModifyTime(source.getModifyTime());
            target.setModifyBy(source.getModifyBy());
            return target;
        }
        return null;
    }
}
